const interpret = (arr, cmds) => {
    cmds = cmds.toLowerCase();
    //数学函数
    var fn = {
        'plus': (a, b) => a + b,
        'minus': (a, b) => a - b,
        'divide by': (a, b) => a / b,
        'multiply by': (a, b) => a * b,
        'modulo': (a, b) => a % b
    }
    //比较函数
    var cmps = {
        'equals': (a, b) => a === b,
        'not equals': (a, b) => a !== b,
        'greater than': (a, b) => a > b,
        'lesser than': (a, b) => a < b,
        'not greater than': (a, b) => a <= b,
        'not lesser than': (a, b) => a >= b
    }

    //与和或函数
    var fn_bool = {
        'and': (a, b) => a && b,
        'or': (a, b) => a || b
    }

    /*解析部分*/
    //数学操作
    var operator = '(plus|minus|(multiply by)|(divide by)|modulo)';
    var number = '-?\\d+';
    var math = `${operator}( ${number})?`
    var maths = `${operator}( ${number})?( then ${operator}( ${number})?)*`
    //比较操作
    var cmp = '(not )?(equals|(greater than)|(lesser than))';
    var conditon = `(${math} )?${cmp} ${number}`;
    var comb = '(and|or)';
    var conditons = `${conditon}( ${comb} ${conditon})*`;
    var _return = `${comb} return if ${conditons}`;
    var returns = `${comb} return if ${conditons}( ${comb} return if ${conditons})*`;

    var map = `map (the array )?with ${maths}`;
    var reduce = `reduce (the array )?with ${operator}`;
    var filter = `filter (the array )?${returns}`;
    var compose = `${map}|${reduce}|${filter}`;
    //解析命令为数组
    //var cmds = cmds.split(/(?=(map|filter|reduce))/g).map(v => v.replace(/ then ?$/, ''))
    cmds = cmds.match(new RegExp(compose, 'gi'));
    //cmds = cmds.filter(v => !/^((map)|(filter)|(reduce))$/.test(v));
    //这玩意儿有毛病？
    console.log(cmds)
    /*功能函数(Map,Filter,Reduce)实现部分*/
    function fun_map(cmd, inp_arr) {
        var arithmetics = cmd.match(new RegExp(math, 'g'));
        for (s of arithmetics) {
            var [p, k] = s.match(new RegExp(`${operator}|${number}`, 'g'));
            var f = fn[p];
            inp_arr = inp_arr.map(v => f(v, +k))
        }
        return inp_arr;
    }

    function fun_reduce(cmd, inp_arr) {
        var p = cmd.match(new RegExp(`${math}`))[0];
        var f = fn[p];
        return inp_arr.reduce((s, v) => f(s, v));
    }

    function fun_filter(cmd, inp_arr) {
        var rs = cmd.match(new RegExp(returns))[0]
        rs = rs.replace(/and return if/g, 'and').replace(/or return if/g, 'or')

        var filter_res = [];
        var cond_str = rs.match(new RegExp(conditons, 'g'))[0];
        var conds = cond_str.match(new RegExp(`(${comb} )?${conditon}`, 'g'));
        var ralations = conds.slice(1).map(v => v.split(' ')[0]);
        var bools = [];
        var compares = []
        for (x of conds) {
            var prefix = new RegExp(`^${comb} `);
            if (prefix.test(x)) x = x.replace(prefix, '');
            var temp = x.match(new RegExp(`(${math})|(${cmp})|(${number})`, 'g'));
            var a, compare, b;
            if (temp.length === 3) {
                [a, compare, b] = temp;
            } else {
                a = null;
                [compare, b] = temp;
            }
            compares.push([a, compare, b]);
        }
        for (var i = 0; i < inp_arr.length; i++) {
            var x = inp_arr[i];
            var bools = []
            for ([a, compare, b] of compares) {
                if (!a) a = x; else {
                    var [p, k] = a.match(new RegExp(`${operator}|${number}`, 'g'));
                    var f = fn[p];
                    a = f(x, +k);
                }
                var cmp_f = cmps[compare];
                bools.push(cmp_f(a, +b))
            }

            var check = bool_calc(bools, ralations)
            /*for (r of ralations) {
                check = fn_bool[r](check, bools.shift())
            }*/
            if (check) filter_res.push(x);
        }
        return filter_res;
    }
    //根据解析的命令数组实现对数组操作
    for (cmd of cmds) {
        if (new RegExp(map).test(cmd)) arr = fun_map(cmd, arr);
        else if (new RegExp(reduce).test(cmd)) return fun_reduce(cmd, arr);
        else if (new RegExp(filter).test(cmd)) arr = fun_filter(cmd, arr);
    }
    return arr
};

function bool_calc(bools, relations) {
    var exp = '';
    for (var i = 0; i < bools.length; i++) {
        exp += bools[i] ? '1' : '0';
        if (i < relations.length) exp += relations[i] === 'and' ? '&&' : '||';
    }
    while (/\d&&\d/.test(exp)) exp = exp.replace(/(\d)&&(\d)/, (_, a, b) => (+a && +b) ? '1' : '0')
    while (/\d\|\|\d/.test(exp)) exp = exp.replace(/(\d)\|\|(\d)/, (_, a, b) => (+a || +b) ? '1' : '0')
    return Boolean(+exp);
}